package authattemptimpl

import (
	"context"
	"go-caipu/pkg/infra/log"
	"go-caipu/pkg/setting"
	"gorm.io/gorm"
	"time"
)

const (
	maxInvalidLoginAttempts int64 = 5
	loginAttemptsWindow           = time.Minute * 5
)

func ProvideService(d *gorm.DB, cfg *setting.Cfg) *Service {
	return &Service{
		&ormStore{db: d},
		cfg,
		log.New("log_attempt"),
	}
}

type Service struct {
	store store
	cfg   *setting.Cfg

	logger log.Logger
}

func (s *Service) Run(ctx context.Context) error {
	ticker := time.NewTicker(time.Minute * 10)
	for {
		select {
		case <-ticker.C:
			s.cleanup(ctx)
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}

func (s *Service) Add(ctx context.Context, username, ipAddress string) error {
	_, err := s.store.CreateLoginAttempt(ctx, CreateLoginAttemptCommand{
		Username:  username,
		IpAddress: ipAddress,
	})
	return err
}
func (s *Service) Reset(ctx context.Context, username string) error {
	return s.store.DeleteLoginAttempts(ctx, DeleteLoginAttemptsCommand{Username: username})
}
func (s *Service) Validate(ctx context.Context, username string) (bool, error) {
	loginAttemptCountQuery := GetUserLoginAttemptCountQuery{
		Username: username,
		Since:    time.Now().Add(-loginAttemptsWindow),
	}
	count, err := s.store.GetUserLoginAttemptCount(ctx, loginAttemptCountQuery)
	if err != nil {
		return false, err
	}
	if count >= maxInvalidLoginAttempts {
		return false, nil
	}
	return true, nil
}
func (s *Service) cleanup(ctx context.Context) {

}
